home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
public
/
Xpm
/
pixmap
/
Pixmap.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
77KB
|
2,710 lines
/* * Last edited: Jan 2 10:59 1992 (mallet) */
/*
* $Id: Pixmap.c,v 1.10 1992/10/27 08:37:11 mallet Exp $
*
* Copyright 1991 Lionel Mallet
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appears in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Lionel MALLET not be used in
* advertising or publicity pertaining to distribution of the software
* without specific, written prior permission. Lionel MALLET makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
* Lionel MALLET DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL Lionel MALLET BE LIABLE FOR ANY SPECIAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* This software is opened and free. Furthermore, everybody is kindly
* invited to participate to improve it for the benefit of all.
* Improvements can be new features, bugs fixes and porting issues
* resolution.
*
* Author: Lionel Mallet, SIMULOG
*/
/*
* $XConsortium: Pixmap.c,v 1.12 90/06/09 20:19:28 dmatic Exp $
*
* Copyright 1989 Massachusetts Institute of Technology
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of M.I.T. not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. M.I.T. makes no representations about the
* suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*
* M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: Davor Matic, MIT X Consortium
*/
static char rcsid[] = "$Id: Pixmap.c,v 1.10 1992/10/27 08:37:11 mallet Exp $";
#include <X11/IntrinsicP.h>
#include <X11/Xmu/Converters.h>
#include <X11/StringDefs.h>
#include <X11/Xatom.h>
#include <X11/Xos.h>
#include <X11/cursorfont.h>
#include "PixmapP.h"
#include <stdio.h>
#include <math.h>
#define XtStrlen(s) ((s) ? strlen(s) : 0)
#define abs(x) (((x) > 0) ? (x) : -(x))
#define min(x, y) (((x) < (y)) ? (x) : (y))
#define max(x, y) (((x) > (y)) ? (x) : (y))
static Boolean _PWDEBUG = False;
static unsigned int depth;
static int screen;
static Display *dpy;
#define DefaultGridTolerance 5
#define DefaultPixmapWidth 32
#define DefaultPixmapHeight 32
#define DefaultStippled TRUE
#define DefaultGrid TRUE
#define DefaultResize TRUE
#define DefaultProportional TRUE
#define DefaultAxes FALSE
#define DefaultDistance 10
#define DefaultSquareSize 20
static XtResource resources[] = {
#define offset(field) XtOffset(PixmapWidget, pixmap.field)
{XtNcursor, XtCCursor, XtRCursor, sizeof(Cursor),
offset(cursor), XtRString, "tcross"},
{XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
offset(foreground_pixel), XtRString, XtDefaultForeground},
{XtNhighlight, XtCHighlight, XtRPixel, sizeof(Pixel),
offset(highlight_pixel), XtRString, XtDefaultForeground},
{XtNframing, XtCFraming, XtRPixel, sizeof(Pixel),
offset(framing_pixel), XtRString, XtDefaultForeground},
{XtNtransparent, XtCTransparent, XtRPixel, sizeof(Pixel),
offset(transparent_pixel), XtRString, XtDefaultTransparent},
{XtNproportional, XtCProportional, XtRBoolean, sizeof(Boolean),
offset(proportional), XtRImmediate, (XtPointer) DefaultProportional},
{XtNgrid, XtCGrid, XtRBoolean, sizeof(Boolean),
offset(grid), XtRImmediate, (XtPointer) DefaultGrid},
{XtNgridTolerance, XtCGridTolerance, XtRDimension, sizeof(Dimension),
offset(grid_tolerance), XtRImmediate, (XtPointer) DefaultGridTolerance},
{XtNstippled, XtCStippled, XtRBoolean, sizeof(Boolean),
offset(stippled), XtRImmediate, (XtPointer) DefaultStippled},
{XtNaxes, XtCAxes, XtRBoolean, sizeof(Boolean),
offset(axes), XtRImmediate, (XtPointer) DefaultAxes},
{XtNresize, XtCResize, XtRBoolean, sizeof(Boolean),
offset(resize), XtRImmediate, (XtPointer) DefaultResize},
{XtNdistance, XtCDistance, XtRDimension, sizeof(Dimension),
offset(distance), XtRImmediate, (XtPointer) DefaultDistance},
{XtNsquareSize, XtCSquareSize, XtRDimension, sizeof(Dimension),
offset(squareH), XtRImmediate, (XtPointer) DefaultSquareSize},
{XtNsquareSize, XtCSquareSize, XtRDimension, sizeof(Dimension),
offset(squareW), XtRImmediate, (XtPointer) DefaultSquareSize},
{XtNpixmapWidth, XtCPixmapWidth, XtRDimension, sizeof(Dimension),
offset(width), XtRImmediate, (XtPointer) DefaultPixmapWidth},
{XtNpixmapHeight, XtCPixmapHeight, XtRDimension, sizeof(Dimension),
offset(height), XtRImmediate, (XtPointer) DefaultPixmapHeight},
{XtNbutton1Action, XtCButton1Action, XtRInt, sizeof(int),
offset(button_action[0]), XtRImmediate, (XtPointer) Set},
{XtNbutton2Action, XtCButton2Action, XtRInt, sizeof(int),
offset(button_action[1]), XtRImmediate, (XtPointer) Invert},
{XtNbutton3Action, XtCButton3Action, XtRInt, sizeof(int),
offset(button_action[2]), XtRImmediate, (XtPointer) Clear},
{XtNbutton4Action, XtCButton4Action, XtRInt, sizeof(int),
offset(button_action[3]), XtRImmediate, (XtPointer) Clear},
{XtNbutton5Action, XtCButton5Action, XtRInt, sizeof(int),
offset(button_action[4]), XtRImmediate, (XtPointer) Clear},
{XtNfilename, XtCFilename, XtRString, sizeof(String),
offset(filename), XtRImmediate, (XtPointer) XtNscratch},
{XtNaddColorNtfyProc, XtCAddColorNtfyProc, XtRFunction, sizeof(AddColorNotifyProc), offset(AddColorNotify), XtRImmediate, (XtPointer) NULL},
{XtNextensionNtfyProc, XtCExtensionNtfyProc, XtRFunction, sizeof(ExtensionNotifyProc), offset(extensionNotify), XtRImmediate, (XtPointer) NULL},
{XtNstipple, XtCStipple, XtRBitmap, sizeof(Pixmap),
offset(stipple), XtRImmediate, (XtPointer) XtUnspecifiedPixmap},
#undef offset
};
void PWTMark();
void PWTUnmark();
void PWTPaste();
void PWTSetColor();
static XtActionsRec actions[] =
{
{"mark", (XtActionProc)PWTMark},
{"unmark", (XtActionProc)PWTUnmark},
{"paste", (XtActionProc)PWTPaste},
{"set-color", (XtActionProc)PWTSetColor},
{"PW-debug", (XtActionProc)PWDebug},
{"terminate", (XtActionProc)PWTerminate},
{"store-to-buffer", (XtActionProc)PWStoreToBuffer},
{"change-notify", (XtActionProc)PWChangeNotify},
{"set-changed", (XtActionProc)PWSetChanged},
{"up", (XtActionProc)PWUp},
{"down", (XtActionProc)PWDown},
{"left", (XtActionProc)PWLeft},
{"right", (XtActionProc)PWRight},
{"fold", (XtActionProc)PWFold},
{"flip-horiz", (XtActionProc)PWFlipHoriz},
{"flip-vert", (XtActionProc)PWFlipVert},
{"rotate-right", (XtActionProc)PWRotateRight},
{"rotate-left", (XtActionProc)PWRotateLeft},
{"set", (XtActionProc)PWSet},
{"clear", (XtActionProc)PWClear},
{"undo", (XtActionProc)PWUndo},
{"redraw", (XtActionProc)PWRedraw},
};
static char translations[] =
"\
Ctrl<Btn1Down>: mark()\n\
Ctrl<Btn2Down>: paste()\n\
Ctrl<Btn3Down>: unmark()\n\
Shift<BtnUp>: set-color()\n\
Ctrl<Key>l: redraw()\n\
<Key>d: PW-debug()\n\
<Key>t: terminate()\n\
<Key>Up: store-to-buffer()\
up()\
change-notify()\
set-changed()\n\
<Key>Down: store-to-buffer()\
down()\
change-notify()\
set-changed()\n\
<Key>Left: store-to-buffer()\
left()\
change-notify()\
set-changed()\n\
<Key>Right: store-to-buffer()\
right()\
change-notify()\
set-changed()\n\
<Key>f: store-to-buffer()\
fold()\
change-notify()\
set-changed()\n\
<Key>h: store-to-buffer()\
flip-horiz()\
change-notify()\
set-changed()\n\
<Key>v: store-to-buffer()\
flip-vert()\
change-notify()\
set-changed()\n\
<Key>r: store-to-buffer()\
rotate-right()\
change-notify()\
set-changed()\n\
<Key>l: store-to-buffer()\
rotate-left()\
change-notify()\
set-changed()\n\
<Key>s: store-to-buffer()\
set()\
change-notify()\
set-changed()\n\
<Key>c: store-to-buffer()\
clear()\
change-notify()\
set-changed()\n\
<Key>u: undo()\
change-notify()\
set-changed()\n\
";
Atom targets[] = {
XA_BITMAP,
XA_PIXMAP,
XA_STRING,
};
#include "Requests.h"
static void ClassInitialize();
static void Initialize();
static void Redisplay();
static void Resize();
static void InternalResize();
static void Destroy();
static Boolean SetValues();
PixmapClassRec pixmapClassRec = {
{ /* core fields */
/* superclass */ (WidgetClass) &coreClassRec,
/* class_name */ "Pixmap",
/* widget_size */ sizeof(PixmapRec),
/* class_initialize */ ClassInitialize,
/* class_part_initialize */ NULL,
/* class_inited */ FALSE,
/* initialize */ Initialize,
/* initialize_hook */ NULL,
/* realize */ XtInheritRealize,
/* actions */ actions,
/* num_actions */ XtNumber(actions),
/* resources */ resources,
/* num_resources */ XtNumber(resources),
/* xrm_class */ NULLQUARK,
/* compress_motion */ TRUE,
/* compress_exposure */ FALSE,
/* compress_enterleave */ TRUE,
/* visible_interest */ TRUE,
/* destroy */ Destroy,
/* resize */ Resize,
/* expose */ Redisplay,
/* set_values */ SetValues,
/* set_values_hook */ NULL,
/* set_values_almost */ XtInheritSetValuesAlmost,
/* get_values_hook */ NULL,
/* accept_focus */ NULL,
/* version */ XtVersion,
/* callback_private */ NULL,
/* tm_table */ translations,
/* query_geometry */ XtInheritQueryGeometry,
/* display_accelerator */ XtInheritDisplayAccelerator,
/* extension */ NULL,
},
{
/* targets */ targets,
/* num_trets */ XtNumber(targets),
/* requests */ requests,
/* num_requests */ XtNumber(requests),
}
};
WidgetClass pixmapWidgetClass = (WidgetClass) &pixmapClassRec;
#if NeedFunctionPrototypes
Boolean PWQueryGrid(Widget w)
#else
Boolean PWQueryGrid(w)
Widget w;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
return PW->pixmap.grid;
}
#if NeedFunctionPrototypes
Boolean PWQueryAxes(Widget w)
#else
Boolean PWQueryAxes(w)
Widget w;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
return PW->pixmap.axes;
}
#if NeedFunctionPrototypes
Boolean PWQueryStored(Widget w)
#else
Boolean PWQueryStored(w)
Widget w;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
return (PW->pixmap.storage != NULL);
}
#if NeedFunctionPrototypes
Pixel PWGetTransparentPixel(Widget w)
#else
Pixel PWGetTransparentPixel(w)
Widget w;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
return PW->pixmap.transparent_pixel;
}
#if NeedFunctionPrototypes
Pixmap PWGetStipplePixmap(Widget w)
#else
Pixmap PWGetStipplePixmap(w)
Widget w;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
if (PW->pixmap.stippled) return PW->pixmap.stipple;
else return XtUnspecifiedPixmap;
}
#include "Extensions.c"
#include "Graphics.c"
#include "Handlers.c"
#include "ReqMach.c"
#include "CutAndPaste.c"
#if NeedFunctionPrototypes
void PWDebug(Widget w)
#else
void PWDebug(w)
Widget w;
#endif
{
_PWDEBUG ^= True;
XSynchronize(dpy, _PWDEBUG);
}
void PWTSetColor(w, event)
Widget w;
XEvent *event;
{
PixmapWidget PW = (PixmapWidget) w;
PWSetForeground(w,
PWGetPxl(w, InPixmapX(PW, event->xbutton.x),
InPixmapY(PW, event->xbutton.y)));
if (PW->pixmap.colorNotify)
(*PW->pixmap.colorNotify)(w, PW->pixmap.foreground_pixel);
}
#if NeedFunctionPrototypes
void ColorNotify(Widget w, UseColorNotifyProc proc)
#else
void ColorNotify(w, proc)
Widget w;
UseColorNotifyProc proc;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
PW->pixmap.colorNotify = proc;
}
#if NeedFunctionPrototypes
void ExtensionNotify(Widget w, ExtensionNotifyProc proc)
#else
void ExtensionNotify (w, proc)
Widget w;
ExtensionNotifyProc proc;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
PW->pixmap.extensionNotify = proc;
}
#if NeedFunctionPrototypes
void PWPickPixelDraw(Widget w, Position x, Position y, int value)
#else
void PWPickPixelDraw(w, x, y, value)
Widget w;
Position x;
Position y;
int value;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
if (PW->pixmap.pickPixelDraw)
(*PW->pixmap.pickPixelDraw)(w, x, y, value);
}
#if NeedFunctionPrototypes
void PWPickPixelComplete(Widget w, Position x, Position y, int value)
#else
void PWPickPixelComplete(w, x, y, value)
Widget w;
Position x;
Position y;
int value;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
if (PW->pixmap.pickPixelComplete)
(*PW->pixmap.pickPixelComplete)(w, x, y, value);
}
Pixmap GetPixmap(PW, image)
PixmapWidget PW;
XImage *image;
{
Pixmap pix;
XGCValues gcv;
GC gc ;
pix = XCreatePixmap(dpy, XtWindow((Widget) PW),
image->width, image->height, image->depth);
gcv.function = GXcopy;
gc = XCreateGC(dpy, pix, GCFunction, &gcv);
XPutImage(dpy, pix, gc, image, 0, 0, 0, 0,
image->width, image->height);
return(pix);
}
XImage *GetImage(PW, pixmap)
PixmapWidget PW;
Pixmap pixmap;
{
Window root;
int x, y;
unsigned int width, height, border_width, depth;
XImage *image;
XGetGeometry(dpy, pixmap, &root, &x, &y,
&width, &height, &border_width, &depth);
image = XGetImage(dpy, pixmap, x, y, width, height,
AllPlanes, ZPixmap);
return image;
}
XImage *CreateMaskImage(PW, width, height)
PixmapWidget PW;
Dimension width, height;
{
Position x, y;
int bitmap_pad;
XImage *mask_image;
mask_image = XCreateImage(dpy, DefaultVisual(dpy, screen), 1, ZPixmap, 0,
NULL, width, height, 8, 0);
if (!mask_image)
{
XtAppWarning(XtWidgetToApplicationContext((Widget) PW),
"Pixmap error in creating XImage\n");
exit(1);
}
else mask_image->data = XtCalloc(1,
mask_image->bytes_per_line *
mask_image->height);
/* Initialize all pixels to 1: default mask is rectangular */
XAddPixel(mask_image, 1);
return mask_image;
}
XImage *CreatePixmapImage(PW, width, height)
PixmapWidget PW;
Dimension width, height;
{
Position x, y;
int bitmap_pad;
XImage *image;
if (depth <= 8) bitmap_pad = 8;
else if (depth <= 16) bitmap_pad = 16;
else bitmap_pad = 32;
image = XCreateImage(dpy,
DefaultVisual(dpy, screen),
depth,
ZPixmap, 0,
NULL, width, height,
bitmap_pad, 0);
if (!image)
{
XtAppWarning(XtWidgetToApplicationContext((Widget) PW),
"Pixmap error in creating XImage\n");
exit(1);
}
else image->data = XtCalloc(1, image->bytes_per_line * height);
if (WhitePixel(dpy, screen) != 0) /* to clear the image, hope white is or 0
or greater then black */
XAddPixel(image, WhitePixel(dpy, screen)); /* because image pixels are
initialized to 0 */
if (_PWDEBUG) {
printf("bytes_per_line %d\n", image->bytes_per_line);
printf("size data %d\n", image->bytes_per_line * height);
printf("bitmap pad %d\n", image->bitmap_pad);
}
return image;
}
void DestroyPixmapImage(image)
XImage **image;
{
if (*image)
{
XDestroyImage(*image);
*image = NULL;
}
}
#if NeedFunctionPrototypes
XImage *PWGetImage(Widget w)
#else
XImage *PWGetImage(w)
Widget w;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
return PW->pixmap.image;
}
#if NeedFunctionPrototypes
void PWChangeNotify(Widget w, XtPointer client_data, XtPointer call_data)
#else
void PWChangeNotify(w, client_data, call_data)
Widget w;
XtPointer client_data;
XtPointer call_data;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
if (PW->pixmap.notify)
(*PW->pixmap.notify)(w, client_data, call_data);
}
#if NeedFunctionPrototypes
void Notify(Widget w, void (*proc)())
#else
void Notify(w, proc)
Widget w;
void (*proc)();
#endif
{
PixmapWidget PW = (PixmapWidget) w;
PW->pixmap.notify = proc;
}
#if NeedFunctionPrototypes
void PWSetChanged(Widget w)
#else
void PWSetChanged(w)
Widget w;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
PW->pixmap.changed = True;
}
#if NeedFunctionPrototypes
Boolean PWQueryChanged(Widget w)
#else
Boolean PWQueryChanged(w)
Widget w;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
return PW->pixmap.changed;
}
#if NeedFunctionPrototypes
void PWClearChanged(Widget w)
#else
void PWClearChanged(w)
Widget w;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
PW->pixmap.changed = False;
}
#if NeedFunctionPrototypes
void PWSelect(Widget w, Position from_x, Position from_y,
Position to_x, Position to_y, Time time)
#else
void PWSelect(w, from_x, from_y, to_x, to_y, time)
Widget w;
Position from_x, from_y, to_x, to_y;
Time time;
#endif
{
PWMark(w, from_x, from_y, to_x, to_y);
PWGrabSelection(w, time);
}
#if NeedFunctionPrototypes
void PWSwitchAxes(Widget w)
#else
void PWSwitchAxes(w)
Widget w;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
PW->pixmap.axes ^= True;
PWHighlightAxes(w);
}
#if NeedFunctionPrototypes
void PWAxes(Widget w, Boolean _switch)
#else
void PWAxes(w, _switch)
Widget w;
Boolean _switch;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
if (PW->pixmap.axes != _switch)
PWSwitchAxes(w);
}
#if NeedFunctionPrototypes
void PWRedrawAxes(Widget w)
#else
void PWRedrawAxes(w)
Widget w;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
if (PW->pixmap.axes)
PWHighlightAxes(w);
}
#if NeedFunctionPrototypes
void PWPutImage(Widget w, Display *display, Drawable drawable, GC gc,
Position x, Position y)
#else
void PWPutImage(w, display, drawable, gc, x, y)
PixmapWidget w;
Display *display;
Drawable drawable;
GC gc;
Position x, y;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
XPutImage(display, drawable, gc, PW->pixmap.image,
0, 0, x, y, PW->pixmap.image->width, PW->pixmap.image->height);
}
String StripFilename(filename)
String filename;
{
char *begin = rindex (filename, '/');
char *end, *result;
int length;
if (filename) {
begin = (begin ? begin + 1 : filename);
end = index (begin, '.'); /* change to rindex to allow longer names */
length = (end ? (end - begin) : strlen (begin));
result = (char *) XtMalloc (length + 1);
strncpy (result, begin, length);
result [length] = '\0';
return (result);
}
else
return (XtNdummy);
}
void SetTransparentPixels(pw, image, mask_image)
PixmapWidget pw;
XImage *image, *mask_image;
{
register Position x, y;
for (x = 0; x < image->width; x++)
for (y = 0; y < image->height; y++)
if (XGetPixel(mask_image, x, y) == 0)
XPutPixel(image, x, y, pw->pixmap.transparent_pixel);
}
char *ReadColorsInUse(image, mask_image, attribs)
XImage *image;
XpmAttributes *attribs;
{
/* Used array is mallocd'ed here and should therefore be freed by caller */
char *Used = (char *)XtCalloc(1<<depth, sizeof(char)); /* without transp. */
register Position x, y;
register Pixel pxl;
for (x = 0; x < image->width; x++)
for (y = 0; y < image->height; y++)
{
pxl = GetPxlFromImageAndMask(image, mask_image, x, y);
if (pxl == TRANSPARENT(dpy, screen))
{
if (!attribs->mask_pixel) {
attribs->mask_pixel = 1;
attribs->ncolors++;
}
}
else if (!Used[pxl])
{
Used[pxl]++;
attribs->ncolors++;
}
}
return Used;
}
void InitializeXpmAttributes(attribs)
XpmAttributes *attribs;
{
attribs->visual = (Visual *)0;
attribs->colormap = (Colormap)0;
attribs->depth = 0;
attribs->width = 0;
attribs->height = 0;
attribs->x_hotspot = 0;
attribs->y_hotspot = 0;
attribs->cpp = 0;
attribs->pixels = (Pixel *)0;
attribs->npixels = 0;
attribs->colorsymbols = (XpmColorSymbol *)0;
attribs->numsymbols = 0;
attribs->rgb_fname = NULL;
attribs->nextensions = 0;
attribs->extensions = (XpmExtension *)0;
attribs->ncolors = 0;
attribs->colorTable = NULL;
attribs->hints_cmt = NULL;
attribs->colors_cmt = NULL;
attribs->pixels_cmt = NULL;
attribs->mask_pixel = 0;
}
#if NeedFunctionPrototypes
void PWGetUnzoomedPixmap(Widget w, Pixmap *pixmap, Pixmap *pixmap_mask)
#else
void PWGetUnzoomedPixmap(w, pixmap, pixmap_mask)
Widget w;
Pixmap *pixmap, *pixmap_mask;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
XImage *mask_image, *image;
if (PW->pixmap.zooming)
{
image = CreatePixmapImage(PW,
(Dimension) PW->pixmap.zoom.image->width,
(Dimension) PW->pixmap.zoom.image->height);
CopyImageData(PW->pixmap.zoom.image, image, 0, 0,
(Dimension) PW->pixmap.zoom.image->width,
(Dimension) PW->pixmap.zoom.image->height, 0, 0);
CopyImageData(PW->pixmap.image, image,
0, 0,
PW->pixmap.image->width - 1,
PW->pixmap.image->height - 1,
PW->pixmap.zoom.at_x, PW->pixmap.zoom.at_y);
mask_image = CreateMaskImage(PW,
(Dimension)PW->pixmap.zoom.image->width,
(Dimension)PW->pixmap.zoom.image->height);
CopyImageData(PW->pixmap.zoom.mask_image, mask_image, 0, 0,
(Dimension) PW->pixmap.zoom.mask_image->width,
(Dimension) PW->pixmap.zoom.mask_image->height, 0, 0);
CopyImageData(PW->pixmap.mask_image, mask_image,
0, 0,
PW->pixmap.mask_image->width - 1,
PW->pixmap.mask_image->height - 1,
PW->pixmap.zoom.at_x, PW->pixmap.zoom.at_y);
}
else
{
image = PW->pixmap.image;
mask_image = PW->pixmap.mask_image;
}
*pixmap = GetPixmap(PW, image);
*pixmap_mask = GetPixmap(PW, mask_image);
if (PW->pixmap.zooming) {
DestroyPixmapImage(&image);
DestroyMaskImage(&mask_image);
}
}
void Refresh();
static void ClassInitialize()
{
static XtConvertArgRec screenConvertArg[] = {
{XtWidgetBaseOffset, (XtPointer) XtOffset(Widget, core.screen),
sizeof(Screen *)},
};
XtAddConverter(XtRString, XtRBitmap, XmuCvtStringToBitmap,
screenConvertArg, XtNumber(screenConvertArg));
}
static void Initialize(request, new, argv, argc)
PixmapWidget request, new;
ArgList argv;
Cardinal argc;
{
XGCValues values;
XtGCMask mask;
dpy = XtDisplay(new);
screen = DefaultScreen(dpy);
depth = DefaultDepth(dpy,screen);
/* allocate max colors + 1 colorTable entries because 0 is transparent */
new->pixmap.colorTable = (PWColorInfo **) XtCalloc(1<<depth + 1,
sizeof(PWColorInfo*));
new->pixmap.notify = NULL;
new->pixmap.cardinal = 0;
new->pixmap.current = 0;
new->pixmap.fold = False;
new->pixmap.changed = False;
new->pixmap.zooming = False;
new->pixmap.selection.own = False;
new->pixmap.selection.limbo = False;
new->pixmap.clear_pixel = WhitePixel(dpy, screen);
new->pixmap.hints_cmt = NULL;
new->pixmap.colors_cmt = NULL;
new->pixmap.pixels_cmt = NULL;
new->pixmap.filename = XtNewString(new->pixmap.filename);
new->pixmap.request_stack = (PWRequestStack *)
XtMalloc(sizeof(PWRequestStack));
new->pixmap.request_stack[0].request = NULL;
new->pixmap.request_stack[0].call_data = NULL;
new->pixmap.request_stack[0].trap = False;
new->core.width = new->pixmap.width * new->pixmap.squareW +
2 * new->pixmap.distance;
new->core.height = new->pixmap.height * new->pixmap.squareH +
2 * new->pixmap.distance;
new->pixmap.extensions = NULL;
new->pixmap.nextensions = 0;
new->pixmap.buffer_extensions = NULL;
new->pixmap.buffer_nextensions = 0;
new->pixmap.text_string = NULL;
new->pixmap.font_struct = NULL;
/*
PWSetFont(new, "-*-fixed-medium-*-*-*-13-*-*-*-*-70-*-*" );
*/
new->pixmap.hot.x = new->pixmap.hot.y = NotSet;
new->pixmap.buffer_hot.x = new->pixmap.buffer_hot.y = NotSet;
new->pixmap.mark.from_x = new->pixmap.mark.from_y = NotSet;
new->pixmap.mark.to_x = new->pixmap.mark.to_y = NotSet;
new->pixmap.buffer_mark.from_x = new->pixmap.buffer_mark.from_y = NotSet;
new->pixmap.buffer_mark.to_x = new->pixmap.buffer_mark.to_y = NotSet;
values.foreground = new->pixmap.foreground_pixel;
values.background = new->core.background_pixel;
values.foreground ^= values.background;
values.function = GXcopy;
values.plane_mask = AllPlanes;
mask = GCForeground | GCBackground | GCFunction | GCPlaneMask;
new->pixmap.drawing_gc = XCreateGC(dpy, RootWindow(dpy,screen),
mask, &values);
values.foreground = new->pixmap.highlight_pixel;
values.background = new->core.background_pixel;
values.foreground ^= values.background;
values.function = GXxor;
values.plane_mask = AllPlanes;
mask = GCForeground | GCBackground | GCFunction | GCPlaneMask;
new->pixmap.highlighting_gc = XCreateGC(dpy, RootWindow(dpy, screen),
mask, &values);
values.foreground = new->pixmap.framing_pixel;
values.background = new->core.background_pixel;
values.foreground ^= values.background;
values.function = GXxor;
values.plane_mask = AllPlanes;
mask = GCForeground | GCBackground | GCFunction | GCPlaneMask;
new->pixmap.framing_gc = XCreateGC(dpy, RootWindow(dpy, screen),
mask, &values);
values.foreground = new->pixmap.transparent_pixel;
values.background = new->pixmap.clear_pixel;
values.function = GXcopy;
mask = GCForeground | GCBackground | GCFunction;
if (new->pixmap.stipple != XtUnspecifiedPixmap)
{
values.stipple = new->pixmap.stipple;
mask |= GCStipple | GCFillStyle;
}
values.fill_style = (new->pixmap.stippled ?
FillOpaqueStippled : FillSolid);
new->pixmap.transparent_gc = XCreateGC(dpy, RootWindow(dpy, screen),
mask, &values);
new->pixmap.storage = NULL;
new->pixmap.image = CreatePixmapImage(new,
new->pixmap.width,
new->pixmap.height);
new->pixmap.mask_image = CreateMaskImage(new,
new->pixmap.width,
new->pixmap.height);
new->pixmap.buffer = CreatePixmapImage(new,
new->pixmap.width,
new->pixmap.height);
new->pixmap.mask_buffer = CreateMaskImage(new,
new->pixmap.width,
new->pixmap.height);
/* add transparent pixel in ColorTable */
PWUseColorInTable((Widget)new, TRANSPARENT(dpy, screen), NULL,
NULL, NULL, NULL, NULL, NoColorName);
if (new->pixmap.AddColorNotify != (AddColorNotifyProc) 0)
new->pixmap.AddColorNotify((Widget)new, TRANSPARENT(dpy, screen),
NoColorName);
/* add clear pixel in ColorTable */
PWUseColorInTable((Widget)new, new->pixmap.clear_pixel, NULL,
NULL, NULL, NULL, NULL, "white");
if (new->pixmap.AddColorNotify != (AddColorNotifyProc) 0)
new->pixmap.AddColorNotify((Widget)new, new->pixmap.clear_pixel,
"white");
/* Read file */
{
int status;
XImage *image, *mask_image, *buffer, *mask_buffer;
char *buffer_data;
XpmAttributes attribs;
InitializeXpmAttributes(&attribs);
attribs.visual = DefaultVisual(dpy, screen);
attribs.colormap = DefaultColormap(dpy, screen);
attribs.depth = depth;
attribs.colorsymbols = (XpmColorSymbol *)NULL;
attribs.numsymbols = 0;
attribs.nextensions = 0;
attribs.valuemask = XpmVisual | XpmColormap | XpmDepth |
XpmReturnPixels | XpmReturnInfos | XpmExtensions;
status = XpmReadFileToImage(dpy, new->pixmap.filename, &image,
&mask_image, &attribs);
if (status == XpmSuccess)
{
{ /* Notify colors to be loaded with this pixmap */
int i, shift = 0, offset;
switch (depth)
{
case 1:
offset = 2;
break;
case 4:
offset = 3;
break;
case 6:
offset = 4;
break;
case 8:
default:
offset = 5;
break;
}
for (i = 0; i < attribs.ncolors; i++)
{
if (_PWDEBUG) {
printf("Pixel %d\n", *(attribs.pixels+i-shift));
printf("Color name %s\n",
*(*(attribs.colorTable+i)+offset));
printf("colorTable[%d][0] %s\n", i,
**(attribs.colorTable+i));
printf("colorTable[%d][1] %s\n", i,
*(*(attribs.colorTable+i)+1));
printf("colorTable[%d][2] %s\n", i,
*(*(attribs.colorTable+i)+2));
printf("colorTable[%d][3] %s\n", i,
*(*(attribs.colorTable+i)+3));
printf("colorTable[%d][4] %s\n", i,
*(*(attribs.colorTable+i)+4));
printf("colorTable[%d][5] %s\n", i,
*(*(attribs.colorTable+i)+5));
}
if ((attribs.mask_pixel != UNDEF_PIXEL) &&
(i == attribs.mask_pixel))
{
PWUpdateColorInTable((Widget)new,
TRANSPARENT(dpy, screen),
*(*(attribs.colorTable+i)),
*(*(attribs.colorTable+i)+1),
*(*(attribs.colorTable+i)+2),
*(*(attribs.colorTable+i)+3),
*(*(attribs.colorTable+i)+4),
*(*(attribs.colorTable+i)+5));
shift = 1;
}
else
{
PWUseColorInTable((Widget)new,
*(attribs.pixels+i-shift),
*(*(attribs.colorTable+i)),
*(*(attribs.colorTable+i)+1),
*(*(attribs.colorTable+i)+2),
*(*(attribs.colorTable+i)+3),
*(*(attribs.colorTable+i)+4),
*(*(attribs.colorTable+i)+5));
if (new->pixmap.AddColorNotify != (AddColorNotifyProc) 0)
new->pixmap.AddColorNotify((Widget)new,
*(attribs.pixels+i-shift),
*(*(attribs.colorTable+i)
+offset));
}
}
if (new->pixmap.hints_cmt) XtFree(new->pixmap.hints_cmt);
if (attribs.hints_cmt)
new->pixmap.hints_cmt = XtNewString(attribs.hints_cmt);
if (new->pixmap.colors_cmt) XtFree(new->pixmap.colors_cmt);
if (attribs.colors_cmt)
new->pixmap.colors_cmt = XtNewString(attribs.colors_cmt);
if (new->pixmap.pixels_cmt) XtFree(new->pixmap.pixels_cmt);
if (attribs.pixels_cmt)
new->pixmap.pixels_cmt = XtNewString(attribs.pixels_cmt);
}
if (!mask_image) /* Xpm returns NULL when transp. is not used */
mask_image = CreateMaskImage(new, image->width, image->height);
else SetTransparentPixels(new, image, mask_image);
buffer = CreatePixmapImage(new, new->pixmap.image->width,
new->pixmap.image->height);
mask_buffer = CreateMaskImage(new, new->pixmap.image->width,
new->pixmap.image->height);
TransferImageData(new->pixmap.image, buffer);
TransferImageData(new->pixmap.mask_image, mask_buffer);
DestroyPixmapImage(&new->pixmap.image);
DestroyPixmapImage(&new->pixmap.buffer);
DestroyMaskImage(&new->pixmap.mask_image);
DestroyMaskImage(&new->pixmap.mask_buffer);
new->pixmap.image = image;
new->pixmap.mask_image = mask_image;
new->pixmap.buffer = buffer;
new->pixmap.mask_buffer = mask_buffer;
new->pixmap.width = attribs.width;
new->pixmap.height = attribs.height;
if (attribs.valuemask & XpmHotspot)
{
new->pixmap.hot.x = attribs.x_hotspot;
new->pixmap.hot.y = attribs.y_hotspot;
}
CopyExtensions( &new->pixmap.extensions, &new->pixmap.nextensions,
attribs.extensions, attribs.nextensions );
if (new->pixmap.extensionNotify)
new->pixmap.extensionNotify ((Widget) new);
new->pixmap.changed = False;
new->pixmap.zooming = False;
XpmFreeAttributes(&attribs);
}
}
InternalResize(new);
Resize(new);
}
#if NeedFunctionPrototypes
Boolean PWQueryMarked(Widget w)
#else
Boolean PWQueryMarked(w)
Widget w;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
return QuerySet(PW->pixmap.mark.from_x, PW->pixmap.mark.from_y);
}
#if NeedFunctionPrototypes
Boolean PWQueryStippled(Widget w)
#else
Boolean PWQueryStippled(w)
Widget w;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
return(PW->pixmap.stippled);
}
void FixMark(PW)
PixmapWidget PW;
{
if (QuerySet(PW->pixmap.mark.from_x, PW->pixmap.mark.from_y)) {
PW->pixmap.mark.from_x = min(PW->pixmap.mark.from_x,
PW->pixmap.image->width);
PW->pixmap.mark.from_y = min(PW->pixmap.mark.from_y,
PW->pixmap.image->height);
PW->pixmap.mark.to_x = min(PW->pixmap.mark.to_x,
PW->pixmap.image->width);
PW->pixmap.mark.to_y = min(PW->pixmap.mark.to_y,
PW->pixmap.image->height);
if((PW->pixmap.mark.from_x == PW->pixmap.mark.from_y) &&
(PW->pixmap.mark.to_x == PW->pixmap.mark.to_y))
PW->pixmap.mark.from_x =
PW->pixmap.mark.from_y =
PW->pixmap.mark.to_x =
PW->pixmap.mark.to_y = NotSet;
}
}
#if NeedFunctionPrototypes
int PWStoreFile(Widget w, String filename)
#else
int PWStoreFile(w, filename)
Widget w;
String filename;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
int status;
XImage *image, *mask_image;
XpmAttributes attribs;
unsigned int width, height;
InitializeXpmAttributes(&attribs);
attribs.visual = DefaultVisual(dpy, screen);
attribs.colormap = DefaultColormap(dpy, screen);
attribs.depth = depth;
attribs.colorsymbols = (XpmColorSymbol *)NULL;
attribs.numsymbols = 0;
attribs.nextensions = 0;
attribs.valuemask = XpmVisual | XpmColormap | XpmDepth |
XpmReturnPixels | XpmReturnInfos ;
status = XpmReadFileToImage(dpy, filename, &image, &mask_image, &attribs);
if (status == XpmSuccess) {
{ /* Notify colors to be loaded with this pixmap */
int i, offset, shift = 0;
switch (depth)
{
case 1:
offset = 2; /* BW display */
break;
case 4:
offset = 3; /* G4 display */
break;
case 6:
offset = 4; /* G6 display */
break;
case 8:
default:
offset = 5; /* Color display */
break;
}
for (i = 0; i < attribs.ncolors; i++)
{
if (_PWDEBUG) {
printf("Pixel %d\n", *(attribs.pixels+i-shift));
printf("Color name %s\n", *(*(attribs.colorTable+i)+offset));
printf("colorTable[%d][0] %s\n", i, **(attribs.colorTable+i));
printf("colorTable[%d][1] %s\n", i,*(*(attribs.colorTable+i)+1));
printf("colorTable[%d][2] %s\n", i,*(*(attribs.colorTable+i)+2));
printf("colorTable[%d][3] %s\n", i,*(*(attribs.colorTable+i)+3));
printf("colorTable[%d][4] %s\n", i,*(*(attribs.colorTable+i)+4));
printf("colorTable[%d][5] %s\n", i,*(*(attribs.colorTable+i)+5));
}
if ((attribs.mask_pixel != UNDEF_PIXEL) &&
(i == attribs.mask_pixel))
{
PWUpdateColorInTable((Widget)PW, TRANSPARENT(dpy, screen),
*(*(attribs.colorTable+i)),
*(*(attribs.colorTable+i)+1),
*(*(attribs.colorTable+i)+2),
*(*(attribs.colorTable+i)+3),
*(*(attribs.colorTable+i)+4),
*(*(attribs.colorTable+i)+5));
shift = 1;
}
else
{
PWUseColorInTable((Widget)PW, *(attribs.pixels+i-shift),
*(*(attribs.colorTable+i)),
*(*(attribs.colorTable+i)+1),
*(*(attribs.colorTable+i)+2),
*(*(attribs.colorTable+i)+3),
*(*(attribs.colorTable+i)+4),
*(*(attribs.colorTable+i)+5));
if (PW->pixmap.AddColorNotify != (AddColorNotifyProc) 0)
PW->pixmap.AddColorNotify((Widget)PW,
*(attribs.pixels+i-shift),
*(*(attribs.colorTable+i)+offset));
}
}
}
if (!mask_image) /* Xpm returns NULL when transp. is not used */
mask_image = CreateMaskImage(PW, image->width, image->height);
else SetTransparentPixels(PW, image, mask_image);
DestroyPixmapImage(&PW->pixmap.storage);
DestroyMaskImage(&PW->pixmap.mask_storage);
PW->pixmap.storage = image;
PW->pixmap.mask_storage = mask_image;
if (attribs.valuemask & XpmHotspot)
{
PW->pixmap.storage_hot.x = attribs.x_hotspot;
PW->pixmap.storage_hot.y = attribs.y_hotspot;
}
else
{
PW->pixmap.storage_hot.x = PW->pixmap.storage_hot.y = NotSet;
}
XpmFreeAttributes(&attribs);
}
else
XtAppWarning(XtWidgetToApplicationContext(w),
" read file failed. PixmapWidget");
return status;
}
#if NeedFunctionPrototypes
String PWUnparseStatus(Widget w)
#else
String PWUnparseStatus(w)
Widget w;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
sprintf(PW->pixmap.status,
"Filename: %s Size:%dx%d",
PW->pixmap.filename, PW->pixmap.width, PW->pixmap.height);
return PW->pixmap.status;
}
#if NeedFunctionPrototypes
void PWChangeFilename(Widget w, String str)
#else
void PWChangeFilename(w, str)
Widget w;
String str;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
if (str)
if (strcmp(str, "")) {
XtFree(PW->pixmap.filename);
PW->pixmap.filename = XtNewString( str);
}
}
/* Warning this function sets or gets the pixmap comments
* if passing null, a comment is returned, otherwise, it is stored
* memory is allocated for returned comments, should be free by application */
#if NeedFunctionPrototypes
void PWComments(Widget w, char **hints_cmt, char **colors_cmt,
char **pixels_cmt)
#else
void PWComments(w, hints_cmt, colors_cmt, pixels_cmt)
Widget w;
char **hints_cmt, **colors_cmt, **pixels_cmt;
#endif
{
PixmapWidget PW = (PixmapWidget)w;
if ((*hints_cmt) && (PW->pixmap.hints_cmt))
{
XtFree(PW->pixmap.hints_cmt);
PW->pixmap.hints_cmt = XtNewString(*hints_cmt);
}
else if (*hints_cmt) PW->pixmap.hints_cmt = XtNewString(*hints_cmt);
else *hints_cmt = XtNewString(PW->pixmap.hints_cmt);
if ((*colors_cmt) && (PW->pixmap.colors_cmt))
{
XtFree(PW->pixmap.colors_cmt);
PW->pixmap.colors_cmt = XtNewString(*colors_cmt);
}
else if (*colors_cmt) PW->pixmap.colors_cmt = XtNewString(*colors_cmt);
else *colors_cmt = XtNewString(PW->pixmap.colors_cmt);
if ((*pixels_cmt) && (PW->pixmap.pixels_cmt))
{
XtFree(PW->pixmap.pixels_cmt);
PW->pixmap.pixels_cmt = XtNewString(*pixels_cmt);
}
else if (*pixels_cmt) PW->pixmap.pixels_cmt = XtNewString(*pixels_cmt);
else *pixels_cmt = XtNewString(PW->pixmap.pixels_cmt);
}
#if NeedFunctionPrototypes
void PWAddColorNotifyProc(Widget w, AddColorNotifyProc proc)
#else
void PWAddColorNotifyProc(w, proc)
Widget w;
AddColorNotifyProc proc;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
PW->pixmap.AddColorNotify = proc;
}
#if NeedFunctionPrototypes
PWColorInfo **PWGetColorTable(Widget w)
#else
PWColorInfo **PWGetColorTable(w)
Widget w;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
return(PW->pixmap.colorTable);
}
#if NeedFunctionPrototypes
void PWUseColorInTable(Widget w, Pixel pixel, char *symbol, char *sname,
char *mname, char *g4name, char *gname, char *cname)
#else
void PWUseColorInTable(w, pixel, symbol, sname, mname, g4name, gname, cname)
Widget w;
Pixel pixel;
char *symbol, *sname, *mname, *g4name, *gname, *cname;
#endif
/* name are not used as is, instead memory is malloc'ed to fit in */
{
PixmapWidget PW = (PixmapWidget) w;
/* index in colorTable is 0 for transparent and pixel+1 for others */
int index = (pixel == TRANSPARENT(dpy, screen) ? 0 : pixel + 1);
if (!PW->pixmap.colorTable[index]) /* not yet used color
probably not in colorTable */
{
PW->pixmap.colorTable[index]=(PWColorInfo*)XtCalloc(1,
sizeof(PWColorInfo));
PW->pixmap.colorTable[index]->symbol = 0;
PW->pixmap.colorTable[index]->s_name = 0;
PW->pixmap.colorTable[index]->m_name = 0;
PW->pixmap.colorTable[index]->g4_name = 0;
PW->pixmap.colorTable[index]->g_name = 0;
PW->pixmap.colorTable[index]->c_name = 0;
PW->pixmap.colorTable[index]->pixel = pixel;
}
PWUpdateColorInTable(w, pixel, symbol, sname, mname, g4name,
gname, cname);
}
#if NeedFunctionPrototypes
void PWUpdateColorInTable(Widget w, Pixel pixel, char *symbol, char *sname,
char *mname, char *g4name, char *gname, char *cname)
#else
void PWUpdateColorInTable(w, pixel, symbol, sname, mname, g4name, gname, cname)
Widget w;
Pixel pixel;
char *symbol, *sname, *mname, *g4name, *gname, *cname;
#endif
/* name are not used as is, instead memory is malloc'ed to fit in */
{
PixmapWidget PW = (PixmapWidget) w;
/* index in colorTable is 0 for transparent and pixel+1 for others */
int index = (pixel == TRANSPARENT(dpy, screen) ? 0 : pixel + 1);
if (!PW->pixmap.colorTable[index]) return; /* inexistent color in Table */
/* Update the color info in ColorTable */
if ((symbol) && ((!PW->pixmap.colorTable[index]->symbol) ||
(strcmp(symbol, PW->pixmap.colorTable[index]->symbol))))
{
if (PW->pixmap.colorTable[index]->symbol)
XtFree(PW->pixmap.colorTable[index]->symbol);
PW->pixmap.colorTable[index]->symbol = XtNewString(symbol);
}
if ((sname) && ((!PW->pixmap.colorTable[index]->s_name) ||
(strcmp(sname, PW->pixmap.colorTable[index]->s_name))))
{
if (PW->pixmap.colorTable[index]->s_name)
XtFree(PW->pixmap.colorTable[index]->s_name);
PW->pixmap.colorTable[index]->s_name = XtNewString(sname);
}
if ((mname) && ((!PW->pixmap.colorTable[index]->m_name) ||
(strcmp(mname, PW->pixmap.colorTable[index]->m_name))))
{
if (PW->pixmap.colorTable[index]->m_name)
XtFree(PW->pixmap.colorTable[index]->m_name);
PW->pixmap.colorTable[index]->m_name = XtNewString(mname);
}
if ((g4name) && ((!PW->pixmap.colorTable[index]->g4_name) ||
(strcmp(g4name, PW->pixmap.colorTable[index]->g4_name))))
{
if (PW->pixmap.colorTable[index]->g4_name)
XtFree(PW->pixmap.colorTable[index]->g4_name);
PW->pixmap.colorTable[index]->g4_name = XtNewString(g4name);
}
if ((gname) && ((!PW->pixmap.colorTable[index]->g_name) ||
(strcmp(gname, PW->pixmap.colorTable[index]->g_name))))
{
if (PW->pixmap.colorTable[index]->g_name)
XtFree(PW->pixmap.colorTable[index]->g_name);
PW->pixmap.colorTable[index]->g_name = XtNewString(gname);
}
if ((cname) && ((!PW->pixmap.colorTable[index]->c_name) ||
((strcmp(cname, PW->pixmap.colorTable[index]->c_name)) &&
((cname[0] != '#') ||
(PW->pixmap.colorTable[index]->c_name[0] == '#')))))
{
if (PW->pixmap.colorTable[index]->c_name)
XtFree(PW->pixmap.colorTable[index]->c_name);
PW->pixmap.colorTable[index]->c_name = XtNewString(cname);
}
else if ((!cname) && (!PW->pixmap.colorTable[index]->c_name))
{
XColor color;
color.pixel = pixel;
XQueryColor(dpy, DefaultColormap(dpy, screen), &color);
PW->pixmap.colorTable[index]->c_name = (char *)XtMalloc(15*sizeof(char));
sprintf(PW->pixmap.colorTable[index]->c_name, "#%04X%04X%04X",
color.red, color.green, color.blue);
}
}
#if NeedFunctionPrototypes
int PWReadFile(Widget w, String filename)
#else
int PWReadFile(w, filename)
Widget w;
String filename;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
int status;
XImage *image, *mask_image, *buffer, *mask_buffer;
XpmAttributes attribs;
InitializeXpmAttributes(&attribs);
attribs.visual = DefaultVisual(dpy, screen);
attribs.colormap = DefaultColormap(dpy, screen);
attribs.depth = depth;
attribs.colorsymbols = (XpmColorSymbol *)NULL;
attribs.numsymbols = 0;
attribs.nextensions = 0;
attribs.valuemask = XpmVisual | XpmColormap | XpmDepth |
XpmReturnPixels | XpmReturnInfos | XpmExtensions;
status = XpmReadFileToImage(dpy, filename, &image, &mask_image, &attribs);
if (status == XpmSuccess) {
{ /* Notify colors to be loaded with this pixmap */
int i, offset, shift = 0;
switch (depth)
{
case 1:
offset = 2; /* BW display */
break;
case 4:
offset = 3; /* G4 display */
break;
case 6:
offset = 4; /* G6 display */
break;
case 8:
default:
offset = 5; /* Color display */
break;
}
for (i = 0; i < attribs.ncolors; i++)
{
if (_PWDEBUG) {
printf("Pixel %d\n", *(attribs.pixels+i-shift));
printf("Color name %s\n", *(*(attribs.colorTable+i)+offset));
printf("colorTable[%d][0] %s\n", i,**(attribs.colorTable+i));
printf("colorTable[%d][1] %s\n", i,*(*(attribs.colorTable+i)+1));
printf("colorTable[%d][2] %s\n", i,*(*(attribs.colorTable+i)+2));
printf("colorTable[%d][3] %s\n", i,*(*(attribs.colorTable+i)+3));
printf("colorTable[%d][4] %s\n", i,*(*(attribs.colorTable+i)+4));
printf("colorTable[%d][5] %s\n", i,*(*(attribs.colorTable+i)+5));
}
if ((attribs.mask_pixel != UNDEF_PIXEL) &&
(i == attribs.mask_pixel))
{
PWUpdateColorInTable((Widget)PW, TRANSPARENT(dpy, screen),
*(*(attribs.colorTable+i)),
*(*(attribs.colorTable+i)+1),
*(*(attribs.colorTable+i)+2),
*(*(attribs.colorTable+i)+3),
*(*(attribs.colorTable+i)+4),
*(*(attribs.colorTable+i)+5));
shift = 1;
}
else
{
PWUseColorInTable((Widget) PW, *(attribs.pixels+i-shift),
*(*(attribs.colorTable+i)),
*(*(attribs.colorTable+i)+1),
*(*(attribs.colorTable+i)+2),
*(*(attribs.colorTable+i)+3),
*(*(attribs.colorTable+i)+4),
*(*(attribs.colorTable+i)+5));
if (PW->pixmap.AddColorNotify != (AddColorNotifyProc) 0)
PW->pixmap.AddColorNotify((Widget) PW,
*(attribs.pixels+i-shift),
*(*(attribs.colorTable+i)+offset));
}
}
if (PW->pixmap.hints_cmt) XtFree(PW->pixmap.hints_cmt);
if (attribs.hints_cmt)
PW->pixmap.hints_cmt = XtNewString(attribs.hints_cmt);
if (PW->pixmap.colors_cmt) XtFree(PW->pixmap.colors_cmt);
if (attribs.colors_cmt)
PW->pixmap.colors_cmt = XtNewString(attribs.colors_cmt);
if (PW->pixmap.pixels_cmt) XtFree(PW->pixmap.pixels_cmt);
if (attribs.pixels_cmt)
PW->pixmap.pixels_cmt = XtNewString(attribs.pixels_cmt);
}
if (!mask_image) /* Xpm returns NULL when transp. is not used */
mask_image = CreateMaskImage(PW, image->width, image->height);
else SetTransparentPixels(PW, image, mask_image);
buffer = CreatePixmapImage(PW, PW->pixmap.image->width,
PW->pixmap.image->height);
mask_buffer = CreateMaskImage(PW, PW->pixmap.image->width,
PW->pixmap.image->height);
TransferImageData(PW->pixmap.image, buffer);
TransferImageData(PW->pixmap.mask_image, mask_buffer);
DestroyPixmapImage(&PW->pixmap.image);
DestroyPixmapImage(&PW->pixmap.buffer);
DestroyMaskImage(&PW->pixmap.mask_image);
DestroyMaskImage(&PW->pixmap.mask_buffer);
PW->pixmap.image = image;
PW->pixmap.mask_image = mask_image;
PW->pixmap.buffer = buffer;
PW->pixmap.mask_buffer = mask_buffer;
PW->pixmap.width = attribs.width;
PW->pixmap.height = attribs.height;
if (attribs.valuemask & XpmHotspot)
{
PW->pixmap.hot.x = attribs.x_hotspot;
PW->pixmap.hot.y = attribs.y_hotspot;
}
else
{
PW->pixmap.hot.x = PW->pixmap.hot.y = NotSet;
}
CopyExtensions( &PW->pixmap.extensions, &PW->pixmap.nextensions,
attribs.extensions, attribs.nextensions );
if (PW->pixmap.extensionNotify)
PW->pixmap.extensionNotify ((Widget) PW);
PW->pixmap.changed = False;
PW->pixmap.zooming = False;
XtFree(PW->pixmap.filename);
PW->pixmap.filename = XtNewString(filename);
PWUnmark(w);
InternalResize(PW);
if (PW->core.visible) {
XClearArea(dpy, XtWindow(PW),
0, 0,
PW->core.width, PW->core.height,
True);
}
XpmFreeAttributes(&attribs);
}
else
XtAppWarning(XtWidgetToApplicationContext(w),
" read file failed. PixmapWidget");
return status;
}
#if NeedFunctionPrototypes
void PWSetImage(Widget w, XImage *image, XImage *mask_image)
#else
void PWSetImage(w, image, mask_image)
Widget w;
XImage *image, *mask_image;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
XImage *buffer, *mask_buffer;
buffer = CreatePixmapImage(PW,
(Dimension) image->width,
(Dimension) image->height);
mask_buffer = CreateMaskImage(PW,
(Dimension) image->width,
(Dimension) image->height);
TransferImageData(PW->pixmap.image, buffer);
TransferImageData(PW->pixmap.mask_image, mask_buffer);
DestroyPixmapImage(&PW->pixmap.image);
DestroyPixmapImage(&PW->pixmap.buffer);
DestroyMaskImage(&PW->pixmap.mask_image);
DestroyMaskImage(&PW->pixmap.mask_buffer);
PW->pixmap.image = image;
PW->pixmap.mask_image = mask_image;
PW->pixmap.buffer = buffer;
PW->pixmap.mask_buffer = mask_buffer;
PW->pixmap.width = image->width;
PW->pixmap.height = image->height;
InternalResize(PW);
if (PW->core.visible) {
XClearArea(dpy, XtWindow(PW),
0, 0,
PW->core.width, PW->core.height,
True);
}
}
XpmAttributes *fillXpmAttributesStruct(PW, image, mask_image)
PixmapWidget PW;
XImage *image;
XImage *mask_image;
{
XpmAttributes *attribs = (XpmAttributes *)XtCalloc(1, XpmAttributesSize());
int i,j = 0, k = 0;
char *InUse;
attribs->valuemask = XpmRgbFilename | XpmInfos ;
attribs->rgb_fname = XtNewString(rgb_fname);
attribs->npixels = 0;
attribs->cpp = 0;
attribs->numsymbols = 0;
attribs->colorsymbols = NULL;
attribs->ncolors = 0;
attribs->mask_pixel = 0;
attribs->colormap = DefaultColormap(dpy, screen);
attribs->valuemask |= XpmColormap;
attribs->depth = depth;
attribs->valuemask |= XpmDepth;
attribs->width = image->width;
attribs->height = image->height;
attribs->valuemask |= XpmSize;
/* compute number of colors in pixmap */
InUse = ReadColorsInUse(image, mask_image, attribs);
/* now allocate memory space for colors */
attribs->colorTable = (char ***)XtCalloc(attribs->ncolors, sizeof(char **));
if (attribs->mask_pixel)
{ /* store transparent color as first in colorTable */
attribs->npixels = attribs->ncolors - 1;
i = 0; /* the first entry in colorTable is reserved for transparent */
attribs->colorTable[0] = (char **)XtCalloc(6, sizeof(char *));
attribs->colorTable[0][0] =
XtNewString(PW->pixmap.colorTable[i]->symbol);
attribs->colorTable[0][1] =
XtNewString(PW->pixmap.colorTable[i]->s_name);
attribs->colorTable[0][2] =
XtNewString(PW->pixmap.colorTable[i]->m_name);
attribs->colorTable[0][3] =
XtNewString(PW->pixmap.colorTable[i]->g4_name);
attribs->colorTable[0][4] =
XtNewString(PW->pixmap.colorTable[i]->g_name);
attribs->colorTable[0][5] =
XtNewString(PW->pixmap.colorTable[i]->c_name);
j = 1;
}
else attribs->npixels = attribs->ncolors;
/* allocate space for pixels */
attribs->pixels = (Pixel *)XtCalloc(attribs->npixels, sizeof(Pixel));
/* fill in pixels and colorTable */
for (i = j; i < attribs->ncolors; i++)
{
for (k; k < 1<<depth; k++) /* find next used color */
if (InUse[k]) break;
/* remember that k+1 is the colorTable entry of k pixel (0 is transp.) */
attribs->pixels[i-j] = k; /* k should be equal to
PW->pixmap.colorTable[k+1]->pixel */
attribs->colorTable[i] = (char **)XtCalloc(6, sizeof(char *));
attribs->colorTable[i][0] =
XtNewString(PW->pixmap.colorTable[k + 1]->symbol);
attribs->colorTable[i][1] =
XtNewString(PW->pixmap.colorTable[k + 1]->s_name);
attribs->colorTable[i][2] =
XtNewString(PW->pixmap.colorTable[k + 1]->m_name);
attribs->colorTable[i][3] =
XtNewString(PW->pixmap.colorTable[k + 1]->g4_name);
attribs->colorTable[i][4] =
XtNewString(PW->pixmap.colorTable[k + 1]->g_name);
attribs->colorTable[i][5] =
XtNewString(PW->pixmap.colorTable[k + 1]->c_name);
k++;
}
/* fill in comments */
attribs->hints_cmt = XtNewString(PW->pixmap.hints_cmt);
attribs->colors_cmt = XtNewString(PW->pixmap.colors_cmt);
attribs->pixels_cmt = XtNewString(PW->pixmap.pixels_cmt);
/* free InUse array */
XtFree(InUse);
/* return struct */
return(attribs);
}
#if NeedFunctionPrototypes
int PWWriteFile(Widget w, String filename)
#else
int PWWriteFile(w, filename)
Widget w;
String filename;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
XImage *image, *mask_image;
XPoint hot;
int status;
XpmAttributes *attribs;
if (PW->pixmap.zooming) {
image = CreatePixmapImage(PW,
(Dimension) PW->pixmap.zoom.image->width,
(Dimension) PW->pixmap.zoom.image->height);
CopyImageData(PW->pixmap.zoom.image, image, 0, 0,
(Dimension) PW->pixmap.zoom.image->width,
(Dimension) PW->pixmap.zoom.image->height, 0, 0);
CopyImageData(PW->pixmap.image, image,
0, 0,
PW->pixmap.image->width - 1,
PW->pixmap.image->height - 1,
PW->pixmap.zoom.at_x, PW->pixmap.zoom.at_y);
mask_image = CreateMaskImage(PW,
(Dimension)PW->pixmap.zoom.image->width,
(Dimension)PW->pixmap.zoom.image->height);
CopyImageData(PW->pixmap.zoom.mask_image, mask_image, 0, 0,
(Dimension) PW->pixmap.zoom.mask_image->width,
(Dimension) PW->pixmap.zoom.mask_image->height, 0, 0);
CopyImageData(PW->pixmap.mask_image, mask_image,
0, 0,
PW->pixmap.mask_image->width - 1,
PW->pixmap.mask_image->height - 1,
PW->pixmap.zoom.at_x, PW->pixmap.zoom.at_y);
if (QuerySet(PW->pixmap.hot.x, PW->pixmap.hot.y))
{
hot.x = PW->pixmap.hot.x + PW->pixmap.zoom.at_x;
hot.y = PW->pixmap.hot.y + PW->pixmap.zoom.at_y;
}
else hot = PW->pixmap.zoom.hot;
}
else {
image = PW->pixmap.image;
mask_image = PW->pixmap.mask_image;
hot = PW->pixmap.hot;
}
if (filename)
{
XtFree(PW->pixmap.filename);
PW->pixmap.filename = XtNewString(filename);
}
if (_PWDEBUG)
fprintf(stderr, "Saving filename: %s\n", filename);
attribs = fillXpmAttributesStruct(PW, image, mask_image);
if (QuerySet(hot.x, hot.y))
{
attribs->valuemask |= XpmHotspot;
attribs->x_hotspot = hot.x;
attribs->y_hotspot = hot.y;
}
/* need to account for zooming for ports ?? */
attribs->valuemask |= XpmExtensions; /* save extensions */
CopyExtensions( &attribs->extensions, &attribs->nextensions,
PW->pixmap.extensions, PW->pixmap.nextensions );
if (attribs->mask_pixel) attribs->mask_pixel = 0; /* transparent color is
always first in
colorTable */
else attribs->mask_pixel = UNDEF_PIXEL;
status = XpmWriteFileFromImage(dpy, PW->pixmap.filename,
image, mask_image, attribs);
XpmFreeAttributes(attribs);
XtFree((char *)attribs);
if (PW->pixmap.zooming) {
DestroyPixmapImage(&image);
DestroyMaskImage(&mask_image);
}
if (status == XpmSuccess)
PW->pixmap.changed = False;
return status;
}
#if NeedFunctionPrototypes
String PWGetFilename(Widget w, String *str)
#else
String PWGetFilename(w, str)
Widget w;
String *str;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
*str = XtNewString(PW->pixmap.filename);
return *str;
}
#if NeedFunctionPrototypes
String PWGetFilepath(Widget w, String *str)
#else
String PWGetFilepath(w, str)
Widget w;
String *str;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
String end;
*str = XtNewString(PW->pixmap.filename);
end = rindex(*str, '/');
if (end)
*(end + 1) = '\0';
else
**str = '\0';
return *str;
}
void FixHotSpot(PW)
PixmapWidget PW;
{
if (!QueryInPixmap(PW, PW->pixmap.hot.x, PW->pixmap.hot.y))
PW->pixmap.hot.x = PW->pixmap.hot.y = NotSet;
}
void ZoomOut(PW)
PixmapWidget PW;
{
CopyImageData(PW->pixmap.image, PW->pixmap.zoom.image,
0, 0,
PW->pixmap.image->width - 1,
PW->pixmap.image->height - 1,
PW->pixmap.zoom.at_x, PW->pixmap.zoom.at_y);
CopyImageData(PW->pixmap.mask_image, PW->pixmap.zoom.mask_image,
0, 0,
PW->pixmap.mask_image->width - 1,
PW->pixmap.mask_image->height - 1,
PW->pixmap.zoom.at_x, PW->pixmap.zoom.at_y);
DestroyPixmapImage(&PW->pixmap.image);
DestroyPixmapImage(&PW->pixmap.buffer);
DestroyMaskImage(&PW->pixmap.mask_image);
DestroyMaskImage(&PW->pixmap.mask_buffer);
PW->pixmap.image = PW->pixmap.zoom.image;
PW->pixmap.mask_image = PW->pixmap.zoom.mask_image;
PW->pixmap.buffer = PW->pixmap.zoom.buffer;
PW->pixmap.mask_buffer = PW->pixmap.zoom.mask_buffer;
PW->pixmap.width = PW->pixmap.image->width;
PW->pixmap.height = PW->pixmap.image->height;
PW->pixmap.fold = PW->pixmap.zoom.fold;
PW->pixmap.changed |= PW->pixmap.zoom.changed;
PW->pixmap.grid = PW->pixmap.zoom.grid;
if (QuerySet(PW->pixmap.hot.x, PW->pixmap.hot.y)) {
PW->pixmap.hot.x += PW->pixmap.zoom.at_x;
PW->pixmap.hot.y += PW->pixmap.zoom.at_y;
}
else
PW->pixmap.hot = PW->pixmap.zoom.hot;
PW->pixmap.mark.from_x = NotSet;
PW->pixmap.mark.from_y = NotSet;
PW->pixmap.mark.to_x = NotSet;
PW->pixmap.mark.to_y = NotSet;
PW->pixmap.zooming = False;
}
#if NeedFunctionPrototypes
void PWZoomOut(Widget w)
#else
void PWZoomOut(w)
Widget w;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
if (PW->pixmap.zooming) {
ZoomOut(PW);
InternalResize(PW);
if (PW->core.visible)
XClearArea(dpy, XtWindow(PW),
0, 0,
PW->core.width, PW->core.height,
True);
}
}
#if NeedFunctionPrototypes
void PWZoomMarked(Widget w)
#else
void PWZoomMarked(w)
Widget w;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
PWZoomIn(w,
PW->pixmap.mark.from_x, PW->pixmap.mark.from_y,
PW->pixmap.mark.to_x, PW->pixmap.mark.to_y);
}
#if NeedFunctionPrototypes
void PWZoomIn(Widget w, Position from_x, Position from_y,
Position to_x, Position to_y)
#else
void PWZoomIn(w, from_x, from_y, to_x, to_y)
Widget w;
Position from_x, from_y, to_x, to_y;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
XImage *image, *buffer, *mask_image, *mask_buffer;
Dimension width, height, coreWidth, coreHeight;
if (PW->pixmap.zooming)
PWZoomOut(w);
QuerySwap(from_x, to_x);
QuerySwap(from_y, to_y);
from_x = max(0, from_x);
from_y = max(0, from_y);
to_x = min(PW->pixmap.width - 1, to_x);
to_y = min(PW->pixmap.height - 1, to_y);
width = to_x - from_x + 1;
height = to_y - from_y + 1;
image = CreatePixmapImage(PW, width, height);
buffer = CreatePixmapImage(PW, width, height);
mask_image = CreateMaskImage(PW, width, height);
mask_buffer = CreateMaskImage(PW, width, height);
CopyImageData(PW->pixmap.image, image, from_x, from_y, to_x, to_y, 0, 0);
CopyImageData(PW->pixmap.buffer, buffer, from_x, from_y, to_x, to_y, 0, 0);
CopyImageData(PW->pixmap.mask_image, mask_image,
from_x, from_y, to_x, to_y, 0, 0);
CopyImageData(PW->pixmap.mask_buffer, mask_buffer,
from_x, from_y, to_x, to_y, 0, 0);
PW->pixmap.zoom.image = PW->pixmap.image;
PW->pixmap.zoom.buffer = PW->pixmap.buffer;
PW->pixmap.zoom.mask_image = PW->pixmap.mask_image;
PW->pixmap.zoom.mask_buffer = PW->pixmap.mask_buffer;
PW->pixmap.zoom.at_x = from_x;
PW->pixmap.zoom.at_y = from_y;
PW->pixmap.zoom.fold = PW->pixmap.fold;
PW->pixmap.zoom.changed = PW->pixmap.changed;
PW->pixmap.zoom.hot = PW->pixmap.hot;
PW->pixmap.zoom.grid = PW->pixmap.grid;
PW->pixmap.image = image;
PW->pixmap.buffer = buffer;
PW->pixmap.mask_image = mask_image;
PW->pixmap.mask_buffer = mask_buffer;
PW->pixmap.width = width;
PW->pixmap.height = height;
PW->pixmap.changed = False;
PW->pixmap.hot.x -= from_x;
PW->pixmap.hot.y -= from_y;
PW->pixmap.mark.from_x = NotSet;
PW->pixmap.mark.from_y = NotSet;
PW->pixmap.mark.to_x = NotSet;
PW->pixmap.mark.to_y = NotSet;
PW->pixmap.zooming = True;
PW->pixmap.grid = True; /* potencially true, could use a resource here */
FixHotSpot(PW);
coreWidth = PW->core.width;
coreHeight = PW->core.height;
InternalResize(PW);
if (PW->core.visible)
XClearArea(dpy, XtWindow(PW),
0, 0,
coreWidth, coreHeight,
True);
}
XImage *ScalePixmapImage();
#if NeedFunctionPrototypes
void PWRescale(Widget w, Dimension width, Dimension height)
#else
void PWRescale(w, width, height)
Widget w;
Dimension width, height;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
XImage *image, *mask_image, *buffer, *mask_buffer;
if (PW->pixmap.zooming)
ZoomOut(PW);
image = ScalePixmapImage(PW, PW->pixmap.image,
(double) width / (double) PW->pixmap.image->width,
(double) height / (double) PW->pixmap.image->height);
mask_image = ScaleMaskImage(PW, PW->pixmap.mask_image,
(double) width / (double) PW->pixmap.mask_image->width,
(double) height / (double) PW->pixmap.mask_image->height);
DestroyPixmapImage(&PW->pixmap.image);
DestroyMaskImage(&PW->pixmap.mask_image);
PW->pixmap.image = image;
PW->pixmap.mask_image = mask_image;
PW->pixmap.width = image->width;
PW->pixmap.height = image->height;
FixHotSpot(PW);
FixMark(PW);
InternalResize(PW);
if (PW->core.visible)
XClearArea(dpy, XtWindow(PW),
0, 0,
PW->core.width, PW->core.height,
True);
}
#if NeedFunctionPrototypes
Boolean PWQueryZooming(Widget w)
#else
Boolean PWQueryZooming(w)
Widget w;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
return PW->pixmap.zooming;
}
#if NeedFunctionPrototypes
void PWResize(Widget w, Dimension width, Dimension height)
#else
void PWResize(w, width, height)
Widget w;
Dimension width, height;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
XImage *image, *mask_image, *buffer, *mask_buffer;
if (PW->pixmap.zooming)
ZoomOut(PW);
image = CreatePixmapImage(PW, width, height);
mask_image = CreateMaskImage(PW, width, height);
TransferImageData(PW->pixmap.image, image);
TransferImageData(PW->pixmap.mask_image, mask_image);
DestroyPixmapImage(&PW->pixmap.image);
DestroyMaskImage(&PW->pixmap.mask_image);
PW->pixmap.image = image;
PW->pixmap.mask_image = mask_image;
PW->pixmap.width = width;
PW->pixmap.height = height;
FixHotSpot(PW);
FixMark(PW);
InternalResize(PW);
if (PW->core.visible)
XClearArea(dpy, XtWindow(PW),
0, 0,
PW->core.width, PW->core.height,
True);
}
static void Destroy(w)
Widget w;
{
PixmapWidget PW = (PixmapWidget) w;
int i;
/* free colorTable */
for (i = 0; i < 1<<depth; i++)
if (PW->pixmap.colorTable[i])
{
if (PW->pixmap.colorTable[i]->symbol)
XtFree(PW->pixmap.colorTable[i]->symbol);
if (PW->pixmap.colorTable[i]->s_name)
XtFree(PW->pixmap.colorTable[i]->s_name);
if (PW->pixmap.colorTable[i]->m_name)
XtFree(PW->pixmap.colorTable[i]->m_name);
if (PW->pixmap.colorTable[i]->g4_name)
XtFree(PW->pixmap.colorTable[i]->g4_name);
if (PW->pixmap.colorTable[i]->g_name)
XtFree(PW->pixmap.colorTable[i]->g_name);
if (PW->pixmap.colorTable[i]->c_name)
XtFree(PW->pixmap.colorTable[i]->c_name);
XtFree((char *)PW->pixmap.colorTable[i]);
}
XtFree((char *)PW->pixmap.colorTable);
XFreeGC(dpy, PW->pixmap.drawing_gc);
XFreeGC(dpy, PW->pixmap.highlighting_gc);
XFreeGC(dpy, PW->pixmap.framing_gc);
XFreeGC(dpy, PW->pixmap.transparent_gc);
DestroyPixmapImage(&PW->pixmap.image);
DestroyPixmapImage(&PW->pixmap.buffer);
DestroyMaskImage(&PW->pixmap.mask_image);
DestroyMaskImage(&PW->pixmap.mask_buffer);
PWRemoveAllRequests(w);
}
/* internal function that makes a gemotry request to PixmapWidget's parent */
static void InternalResize(PW)
PixmapWidget PW;
{
Dimension w, h, rw, rh;
XtGeometryResult status;
w = 2 * (int)PW->pixmap.distance +
(int)PW->pixmap.width * PW->pixmap.squareW;
h = 2 * (int)PW->pixmap.distance +
(int)PW->pixmap.height * PW->pixmap.squareH;
status = XtMakeResizeRequest((Widget)PW, w, h, &rw, &rh);
if (status == XtGeometryAlmost)
status = XtMakeResizeRequest((Widget)PW, rw, rh, NULL, NULL);
else if (status == XtGeometryNo)
XtWarning("PixmapWidget: Geometry request denied");
}
static void Resize(PW)
PixmapWidget PW;
{
Dimension squareW, squareH;
if (PW->pixmap.resize == True)
{
squareW = max(1,
((int)PW->core.width - 2 * (int)PW->pixmap.distance) /
(int)PW->pixmap.width);
squareH = max(1,
((int)PW->core.height - 2 * (int)PW->pixmap.distance) /
(int)PW->pixmap.height);
if (PW->pixmap.proportional)
PW->pixmap.squareW = PW->pixmap.squareH = min(squareW, squareH);
else {
PW->pixmap.squareW = squareW;
PW->pixmap.squareH = squareH;
}
}
PW->pixmap.horizOffset = max((Position)PW->pixmap.distance,
(Position)(PW->core.width -
PW->pixmap.width *
PW->pixmap.squareW) / 2);
PW->pixmap.vertOffset = max((Position)PW->pixmap.distance,
(Position)(PW->core.height -
PW->pixmap.height *
PW->pixmap.squareH) / 2);
PW->pixmap.grid &= ((PW->pixmap.squareW > PW->pixmap.grid_tolerance) &&
(PW->pixmap.squareH > PW->pixmap.grid_tolerance));
}
static void Redisplay(PW, event, region)
PixmapWidget PW;
XEvent *event;
Region region;
{
if(event->type == Expose) {
if (PW->core.visible) {
Refresh(PW,
event->xexpose.x, event->xexpose.y,
event->xexpose.width, event->xexpose.height);
}
}
}
#if NeedFunctionPrototypes
void PWClip(Widget w, Position from_x, Position from_y,
Position to_x, Position to_y)
#else
void PWClip(w, from_x, from_y, to_x, to_y)
Widget w;
Position from_x, from_y, to_x, to_y;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
XRectangle rectangle;
QuerySwap(from_x, to_x);
QuerySwap(from_y, to_y);
from_x = max(0, from_x);
from_y = max(0, from_y);
to_x = min(PW->pixmap.width - 1, to_x);
to_y = min(PW->pixmap.height - 1, to_y);
rectangle.x = InWindowX(PW, from_x);
rectangle.y = InWindowY(PW, from_y);
rectangle.width = InWindowX(PW, to_x + 1) - InWindowX(PW, from_x);
rectangle.height = InWindowY(PW, to_y + 1) - InWindowY(PW, from_y);
XSetClipRectangles(dpy,
PW->pixmap.highlighting_gc,
0, 0,
&rectangle, 1,
Unsorted);
XSetClipRectangles(dpy,
PW->pixmap.drawing_gc,
0, 0,
&rectangle, 1,
Unsorted);
XSetClipRectangles(dpy,
PW->pixmap.framing_gc,
0, 0,
&rectangle, 1,
Unsorted);
}
#if NeedFunctionPrototypes
void PWUnclip(Widget w)
#else
void PWUnclip(w)
Widget w;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
XRectangle rectangle;
rectangle.x = InWindowX(PW, 0);
rectangle.y = InWindowY(PW, 0);
rectangle.width = InWindowX(PW, PW->pixmap.width) - InWindowX(PW, 0);
rectangle.height = InWindowY(PW, PW->pixmap.height) - InWindowY(PW, 0);
XSetClipRectangles(dpy,
PW->pixmap.highlighting_gc,
0, 0,
&rectangle, 1,
Unsorted);
XSetClipRectangles(dpy,
PW->pixmap.drawing_gc,
0, 0,
&rectangle, 1,
Unsorted);
XSetClipRectangles(dpy,
PW->pixmap.framing_gc,
0, 0,
&rectangle, 1,
Unsorted);
}
void Refresh(PW, x, y, width, height)
PixmapWidget PW;
Position x, y;
Dimension width, height;
{
XRectangle rectangle;
Position i, j;
XDefineCursor(dpy, XtWindow(PW), PW->pixmap.cursor);
rectangle.x = min(x, InWindowX(PW, InPixmapX(PW, x)));
rectangle.y = min(y, InWindowY(PW, InPixmapY(PW, y)));
rectangle.width = max(x + width,
InWindowX(PW, InPixmapX(PW, x + width)+1)) - rectangle.x;
rectangle.height = max(y + height,
InWindowY(PW, InPixmapY(PW, y + height)+1)) - rectangle.y;
XClearArea(dpy, XtWindow(PW),
rectangle.x, rectangle.y,
rectangle.width, rectangle.height,
False);
XSetClipRectangles(dpy,
PW->pixmap.framing_gc,
0, 0,
&rectangle, 1,
Unsorted);
XDrawRectangle(dpy, XtWindow(PW),
PW->pixmap.framing_gc,
InWindowX(PW, 0) - 1, InWindowY(PW, 0) - 1,
InWindowX(PW, PW->pixmap.width) - InWindowX(PW, 0) + 1,
InWindowY(PW, PW->pixmap.height) - InWindowY(PW, 0) + 1);
PWClip((Widget) PW,
InPixmapX(PW, x),InPixmapY(PW, y),
InPixmapX(PW, x + width), InPixmapY(PW, y + height));
PWRedrawSquares((Widget) PW, InPixmapX(PW, x), InPixmapY(PW, y),
InPixmapX(PW, x + width), InPixmapY(PW, y + height));
PWRedrawGrid((Widget) PW,
InPixmapX(PW, x), InPixmapY(PW, y),
InPixmapX(PW, x + width), InPixmapY(PW, y + height));
PWRedrawMark((Widget) PW);
PWRedrawHotSpot((Widget) PW);
if (PW->pixmap.redrawCallback)
PW->pixmap.redrawCallback( (Widget) PW, Set ); /* redraw extensions */
PWRedrawAxes((Widget) PW);
PWUnclip((Widget) PW);
}
#if NeedFunctionPrototypes
void PWSwitchGrid(Widget w)
#else
void PWSwitchGrid(w)
Widget w;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
PW->pixmap.grid ^= TRUE;
PWDrawGrid(w,
0, 0,
PW->pixmap.image->width - 1, PW->pixmap.image->height - 1);
}
#if NeedFunctionPrototypes
void PWGrid(Widget w, Boolean _switch)
#else
void PWGrid(w, _switch)
Widget w;
Boolean _switch;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
if (PW->pixmap.grid != _switch)
PWSwitchGrid(w);
}
static Boolean SetValues(current, request, new)
Widget current, request, new;
{
PixmapWidget p_old = (PixmapWidget) current;
PixmapWidget p_new = (PixmapWidget) new;
PixmapWidget p_req = (PixmapWidget) request;
if ((p_old->pixmap.cursor != p_req->pixmap.cursor) && XtIsRealized(new))
XDefineCursor(XtDisplay(new), XtWindow(new), p_new->pixmap.cursor);
if (p_old->pixmap.squareW != p_req->pixmap.squareW)
{
if ((p_old->pixmap.proportional == True) &&
(p_new->pixmap.squareH != p_new->pixmap.squareW))
p_new->pixmap.squareH = p_new->pixmap.squareW;
InternalResize(p_new);
}
if (p_old->pixmap.squareH != p_req->pixmap.squareH)
{
if ((p_old->pixmap.proportional == True) &&
(p_new->pixmap.squareH != p_new->pixmap.squareW))
p_new->pixmap.squareW = p_new->pixmap.squareH;
InternalResize(p_new);
}
return FALSE;
}
#if NeedFunctionPrototypes
Boolean PWQueryProportional(Widget w)
#else
Boolean PWQueryProportional(w)
Widget w;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
return (PW->pixmap.proportional);
}
#if NeedFunctionPrototypes
void PWSwitchProportional(Widget w)
#else
void PWSwitchProportional(w)
Widget w;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
PW->pixmap.proportional ^= True;
InternalResize(PW);
if (PW->core.visible)
XClearArea(dpy, XtWindow(PW),
0, 0,
PW->core.width, PW->core.height,
True);
}
#if NeedFunctionPrototypes
void PWProportional(Widget w, Boolean _switch)
#else
void PWProportional(w, _switch)
Widget w;
Boolean _switch;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
if (PW->pixmap.proportional != _switch)
PWSwitchProportional(w);
}
#if NeedFunctionPrototypes
void PWSetPickPixelDrawProc( Widget w, PickPixelProc proc )
#else
void PWSetPickPixelDrawProc( w, proc )
Widget w;
PickPixelProc proc;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
PW->pixmap.pickPixelDraw = proc;
}
#if NeedFunctionPrototypes
void PWSetPickPixelCompleteProc( Widget w, PickPixelProc proc )
#else
void PWSetPickPixelCompleteProc( w, proc )
Widget w;
PickPixelProc proc;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
PW->pixmap.pickPixelComplete = proc;
}
#if NeedFunctionPrototypes
void PWSetDrawPointProc( Widget w, PWDrawPointProc proc )
#else
void PWSetDrawPointProc( w, proc )
Widget w;
PWDrawPointProc proc;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
PW->pixmap.drawPointCallback = proc;
}
#if NeedFunctionPrototypes
void PWSetRedrawProc( Widget w, PWRedrawProc proc )
#else
void PWSetRedrawProc( w, proc )
Widget w;
PWRedrawProc proc;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
PW->pixmap.redrawCallback = proc;
}
#if NeedFunctionPrototypes
void PWSetTranslateProc( Widget w, PWTranslateProc proc )
#else
void PWSetTranslateProc( w, proc )
Widget w;
PWTranslateProc proc;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
PW->pixmap.translateCallback = proc;
}
#if NeedFunctionPrototypes
void PWSetRotateProc( Widget w, PWRotateProc proc )
#else
void PWSetRotateProc( w, proc )
Widget w;
PWRotateProc proc;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
PW->pixmap.rotateCallback = proc;
}
#if NeedFunctionPrototypes
void PWSetFlipProc( Widget w, PWFlipProc proc )
#else
void PWSetFlipProc( w, proc )
Widget w;
PWFlipProc proc;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
PW->pixmap.flipCallback = proc;
}
#if NeedFunctionPrototypes
void PWSetFont( Widget w, XFontStruct *font_struct )
#else
void PWSetFont( w, font_struct )
Widget w;
XFontStruct *font_struct;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
PW->pixmap.font_struct = font_struct;
if ( PW->pixmap.font_struct && PW->pixmap.text_string ) {
int direction, ascent, descent;
XCharStruct size;
XTextExtents( PW->pixmap.font_struct,
PW->pixmap.text_string, strlen(PW->pixmap.text_string),
&direction, &ascent, &descent, &size );
PW->pixmap.text_rbearing = size.rbearing;
PW->pixmap.text_lbearing = size.lbearing;
PW->pixmap.text_ascent = size.ascent;
PW->pixmap.text_descent = size.descent;
}
}
#if NeedFunctionPrototypes
void PWSetText( Widget w, String s )
#else
void PWSetText( w, s )
Widget w;
String s;
#endif
{
PixmapWidget PW = (PixmapWidget) w;
PW->pixmap.text_string = XtNewString( s );
if ( PW->pixmap.font_struct && PW->pixmap.text_string ) {
int direction, ascent, descent;
XCharStruct size;
XTextExtents( PW->pixmap.font_struct,
PW->pixmap.text_string, strlen(PW->pixmap.text_string),
&direction, &ascent, &descent, &size );
PW->pixmap.text_rbearing = size.rbearing;
PW->pixmap.text_lbearing = size.lbearing;
PW->pixmap.text_ascent = size.ascent;
PW->pixmap.text_descent = size.descent;
}
}